import http from 'wechat-http'

// 配置接口基础路径
http.baseURL = 'https://live-api.itheima.net'

// 挂载到 wx 全局对象上
wx.http = http

// 配置请求拦截器
http.intercept.request = (config) => {
  // 如果有 token，则添加到请求头中
  const { token } = getApp()
  if (token) {
    // 🔴 注意：小程序是 header 没有 s ，而 axios 是 headers
    // 小程序的 header 默认为 undefined，需进行初始化，否则报错
    config.header = {
      // 为请求头对象添加 token 验证的 Authorization 字段
      Authorization: `Bearer ${token}`,
      // 保留原有的 header
      ...config.header,
    }
  }
  // 返回请求配置对象
  return config
}

// 配置响应拦截器
http.intercept.response = async (response) => {
  // 借鉴了 axios 源码的 HTTP 状态码判断
  if (response.statusCode >= 200 && response.statusCode < 300) {
    // 后端业务状态码错误
    if (response.data.code !== 10000) {
      // 通用错误提示
      wx.utils.toast(response.data.message)
      // 返回一个失败的 Promise 对象, 中断 await 后续代码的执行
      return Promise.reject(response.data.message)
    }
    // 业务状态码正确，才返回正确数据
    return response.data
  }
  // 如果响应状态码为 401，则跳转到登录页
  else if (response.statusCode === 401) {
    // 🔴 如果 401 同时请求的是 /refreshToken，表示两个 token 都过期了，直接跳转到登录页，否则会死循环一直请求 /refreshToken
    if (response.config.url.includes('/refreshToken')) {
      // 获取当前页面实例
      const pages = getCurrentPages()
      const page = pages[pages.length - 1]
      // 401 未授权，跳转到登录页，并将当前页面的路由传递给登录页
      wx.redirectTo({
        url: `/pages/login/index?redirectURL=/${page.route}`,
      })
      // 返回一个失败的 Promise 对象, 中断 await 后续代码的执行
      return Promise.reject(response.data.message)
    }
    // 🟢 通过 refreshToken 重新获取 token
    const app = getApp()
    const res = await http({
      method: 'POST',
      url: '/refreshToken',
      header: {
        Authorization: `Bearer ${app.refreshToken}`,
      },
    })
    // 保存最新的 token
    app.setToken(res.data.token, res.data.refreshToken)
    // 🟢
    // 获取原本请求的配置，并覆盖原本的 Authorization 字段成最新的 token
    response.config.header.Authorization = `Bearer ${res.data.token}`
    // 根据最新的 token 重发请求
    return http(response.config)
  } else {
    // 其他未知错误
    return Promise.reject(response.data.message)
  }
}

export default http
